package com.base.common.core.redis;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisCacheImpl implements CacheUtil{
    private static final Long WEEK = 60 * 60 * 24 * 7L;

    private RedisTemplate<String, Object> redisTemplate;

    private String prefix;

    RedisCacheImpl(RedisTemplate<String, Object> redisTemplate, String prefix) {
        this.redisTemplate = redisTemplate;
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        this.prefix = prefix;
    }

    @Override
    public void setString(String key, String data) {
        redisTemplate.opsForValue().set(prefix + key, data, WEEK, TimeUnit.SECONDS);
    }

    @Override
    public String getString(String key) {
        return (String)redisTemplate.opsForValue().get(prefix + key);
    }

    @Override
    public void setBytes(String key, byte[] data) {
        redisTemplate.opsForValue().set(prefix + key, data, WEEK, TimeUnit.SECONDS);
    }

    @Override
    public byte[] getBytes(String key) {
        return (byte[])redisTemplate.opsForValue().get(prefix + key);
    }

    @Override
    public void setMap(String key, Object mapKey, Object mapValue) {
        redisTemplate.opsForHash().put(key, mapKey, mapValue);
    }

    @Override
    public Object getMap(String key, String mapKey) {
        return redisTemplate.opsForHash().get(key, mapKey);
    }

    @Override
    public Set<String> getKeys(String key) {
        Set<String> keys = redisTemplate.keys(prefix + key);
        Set<String> rkeys = new HashSet<>();
        for (String rkey : keys) {
            rkeys.add(rkey.replaceFirst(prefix, ""));
        }
        return rkeys;
    }

    @Override
    public boolean removeKey(String key) {
        Boolean result = redisTemplate.delete(prefix + key);
        if (result != null) {
            return result;
        } else {
            return false;
        }
    }

    @Override
    public boolean expire(String key, Long time) {
        Boolean result =  redisTemplate.expire(prefix + key, time, TimeUnit.SECONDS);
        if (result != null) {
            return result;
        } else {
            return false;
        }
    }

    @Override
    public Long getExpire(String key) {
        return redisTemplate.getExpire(prefix + key);
    }

    @Override
    public boolean exist(String key) {
        Boolean result = redisTemplate.hasKey(prefix + key);
        if (result != null) {
            return result;
        } else {
            return false;
        }
    }

    @Override
    public Long increase(String key) {
        return redisTemplate.opsForValue().increment(prefix + key, 1L);
    }
}
